import * as ts from 'typescript';
import * as tstl from 'typescript-to-lua';
import * as lua from 'typescript-to-lua/dist/LuaAST';

const for_rule = {
    visitors: {
        [ts.SyntaxKind.ForStatement]: (node: ts.ForStatement, context: tstl.TransformationContext) => {
            try {
                const forStmt = node;
                const initializer = forStmt.initializer;
                const condition = forStmt.condition;
                const incrementor = forStmt.incrementor;
                const body = forStmt.statement;

                // 修复点1：添加空值检查
                if (!initializer || !condition || !incrementor) {
                    return convertToWhileLoop(node, context);
                }

                // 仅处理标准的数值循环模式
                if (ts.isVariableDeclarationList(initializer) && initializer.declarations.length === 1) {
                    const decl = initializer.declarations[0];
                    if (ts.isIdentifier(decl.name) && decl.initializer && ts.isBinaryExpression(condition)) {
                        const varName = decl.name.text;

                        // 修复点2：严格验证条件结构
                        if (!ts.isIdentifier(condition.left) || condition.left.text !== varName) {
                            return convertToWhileLoop(node, context); // 使用自定义回退
                        }

                        const startValue = context.transformExpression(decl.initializer);
                        const conditionRight = context.transformExpression(condition.right);
                        let endValue: tstl.Expression;
                        let stepValue: tstl.Expression = tstl.createNumericLiteral(1);

                        // 处理不同比较运算符
                        switch (condition.operatorToken.kind) {
                            case ts.SyntaxKind.LessThanToken:         // i < end
                                endValue = tstl.createBinaryExpression(conditionRight, 1, '-');
                                break;
                            case ts.SyntaxKind.LessThanEqualsToken:   // i <= end
                                endValue = conditionRight;
                                break;
                            case ts.SyntaxKind.GreaterThanToken:      // i > end
                                endValue = tstl.createBinaryExpression(conditionRight, 1, '+');
                                stepValue = tstl.createNumericLiteral(-1);
                                break;
                            case ts.SyntaxKind.GreaterThanEqualsToken: // i >= end
                                endValue = conditionRight;
                                stepValue = tstl.createNumericLiteral(-1);
                                break;
                            default:
                                return convertToWhileLoop(node, context); // 使用自定义回退
                        }
                  
                        // 解析增量表达式
                        const stepResult = analyzeStepExpression(incrementor, varName, context);
                        if (!stepResult.valid) return convertToWhileLoop(node, context);

                        if (stepResult.step) {
                            stepValue = stepResult.step;
                            if (isStepDirectionConflict(condition.operatorToken.kind, stepValue)) {
                                return convertToWhileLoop(node, context);
                            }
                        }
                        console.log('Step value:', stepValue);
                        // 创建Lua数值for循环
                        return tstl.createForInStatement(
                            [tstl.createIdentifier(varName)],
                            [startValue, endValue, stepValue],
                            context.transformStatements(body)
                        );
                    }
                }
                // 非标准循环转换为while
                return convertToWhileLoop(node, context);
            } catch (error) {
                console.error('Error processing for loop:', error);
                return convertToWhileLoop(node, context); // 确保错误时使用安全回退
            }
        }
    }
};


// 辅助函数：分析步长表达式
function analyzeStepExpression(incrementor: ts.Expression, varName: string, context: tstl.TransformationContext) {
    let step: tstl.Expression | null = null;
    let valid = true;

    if (ts.isPostfixUnaryExpression(incrementor) || ts.isPrefixUnaryExpression(incrementor)) {
        // 处理 i++ 或 ++i
        if (incrementor.operator === ts.SyntaxKind.PlusPlusToken) {
            step = tstl.createNumericLiteral(1);
        } else if (incrementor.operator === ts.SyntaxKind.MinusMinusToken) {
            step = tstl.createNumericLiteral(-1);
        }
    } else if (ts.isBinaryExpression(incrementor)) {
        // 处理 i += n 或 i -= n
        if (incrementor.operatorToken.kind === ts.SyntaxKind.PlusEqualsToken ||
            incrementor.operatorToken.kind === ts.SyntaxKind.MinusEqualsToken) {

            if (ts.isIdentifier(incrementor.left) && incrementor.left.text === varName) {
                const baseValue = incrementor.operator === ts.SyntaxKind.PlusEqualsToken ? 1 : -1;
                if (ts.isNumericLiteral(incrementor.right)) {
                    step = tstl.createNumericLiteral(
                        baseValue * parseInt(incrementor.right.text)
                    );
                } else {
                    const transformed = context.transformExpression(incrementor.right);
                    step = incrementor.operator === ts.SyntaxKind.MinusEqualsToken ?
                        tstl.createUnaryExpression(transformed, '-') :
                        transformed;
                }
            }
        }
    }

    return { valid: !!step, step };
}

// 检查步长方向是否与比较运算符冲突
function isStepDirectionConflict(operator: ts.SyntaxKind, step: tstl.Expression) {
    const isNegativeStep = ts.isNumericLiteral(step) && Number(step.value) < 0;

    return (
        (operator === ts.SyntaxKind.LessThanToken ||
            operator === ts.SyntaxKind.LessThanEqualsToken) && isNegativeStep
    ) || (
            (operator === ts.SyntaxKind.GreaterThanToken ||
                operator === ts.SyntaxKind.GreaterThanEqualsToken) && !isNegativeStep
        );
}

// 转换为while循环的备用方案
// 辅助函数：安全的while循环转换（修复点3）
function convertToWhileLoop(node: ts.ForStatement, context: tstl.TransformationContext) {
    const statements: tstl.Statement[] = [];

    // 转换初始化语句
    if (node.initializer) {
        statements.push(context.transformNode(node.initializer)); // 修改这里
    }

    // 构建循环体
    const loopBody: tstl.Statement[] = [];
    if (node.statement) {
        loopBody.push(...context.transformStatements(node.statement));
    }
    if (node.incrementor) {
        loopBody.push(context.transformNode(node.incrementor)); // 如果incrementor是Statement类型，也需要修改
    }

    // 转换条件表达式
    const condition = node.condition
        ? context.transformExpression(node.condition)
        : tstl.createBooleanLiteral(true);

    statements.push(
        tstl.createWhileStatement(
            condition,
            tstl.createBlock(loopBody)
        )
    );

    return tstl.createBlock(statements);
}

module.exports = for_rule;